/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package devbureau.fstore.common.load.impl;

import devbureau.fstore.common.CustomerData;
import devbureau.fstore.common.ItemData;
import devbureau.fstore.common.OrderData;
import devbureau.fstore.common.OrderLineData;
import devbureau.fstore.common.load.FileWriter;
import devbureau.fstore.util.ExcelStyles;
import java.io.FileOutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


/**
 *
 * @author Vladimir
 */
public class ExcelFileWriter implements FileWriter{
    private static final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
    private String fileFormat = null;

    public ExcelFileWriter(String fileFormat) {
        this.fileFormat = fileFormat;
    }

    public String writeOrder(OrderData order, CustomerData customer) throws Exception {
        List<OrderLineData> orderLineList = order.getLines();

        HSSFWorkbook wb;
        wb = new HSSFWorkbook();
        Map<String, HSSFCellStyle> styles = ExcelStyles.createStyles(wb);

        HSSFSheet sheet = wb.createSheet("накладная");

        // first 7 rows height
        for(int i = 0; i < 7; i++) {
            sheet.createRow(i).setHeightInPoints((float)15);
        }

        Integer currRow = 2;

        // customer and sender rows
        HSSFRow senderTitleRow = sheet.createRow(currRow++);
        senderTitleRow.setHeightInPoints((float)15.75);
        HSSFRow customerTitleRow = sheet.createRow(currRow++);
        customerTitleRow.setHeightInPoints((float)15.75);

        // sets customer and sender rows
        HSSFCell senderCell = senderTitleRow.createCell(1);
        HSSFCell customerCell = customerTitleRow.createCell(1);
        senderCell.setCellValue("Отправитель: ООО \"БИАНКА-XXI\"");
        senderCell.setCellStyle(styles.get(ExcelStyles.SENDER));
        customerCell.setCellValue("Получатель: " + customer.getLabel());
        customerCell.setCellStyle(styles.get(ExcelStyles.CUSTOMER));
        for(int j = 2; j < 4; j++) {
            senderTitleRow.createCell(j).setCellStyle(styles.get(ExcelStyles.SENDER));
            customerTitleRow.createCell(j).setCellStyle(styles.get(ExcelStyles.CUSTOMER));
        }

        // order row
        currRow = 5;
        HSSFRow orderInfoRow = sheet.createRow(currRow);
        orderInfoRow.setHeightInPoints((float)15.75);
        // order number
        HSSFCell orderLabelCell = orderInfoRow.createCell(1);
        orderLabelCell.setCellValue("Накладная № " + order.getId());
        orderLabelCell.setCellStyle(styles.get(ExcelStyles.ORDER_ID));
        // order date
        HSSFCell orderDateCell = orderInfoRow.createCell(4);

        String date = "От " + dateToString(order.getCreated());
        orderDateCell.setCellValue(date);
        orderDateCell.setCellStyle(styles.get(ExcelStyles.ORDER_DATE));

        // table header
        currRow = 7;
        HSSFRow orderLineHeaderRow = sheet.createRow(currRow++);
        orderLineHeaderRow.setHeightInPoints((float)39.75);
        String[] orderLineHeaderTitles = { "НАИМЕНОВАНИЕ ТОВАРА", "РАЗМЕР",
                                        "КОЛ-ВО", "ЦЕНА", "СУММА" };
        for(int i = 0; i < orderLineHeaderTitles.length; i++) {
            HSSFCell cell = orderLineHeaderRow.createCell(i + 1);
            cell.setCellValue(orderLineHeaderTitles[i]);
            cell.setCellStyle(styles.get(ExcelStyles.ORDER_TABLE_HEADER));
        }

        String[] orderLineStyles = { ExcelStyles.ORDER_LINE_LABEL,
                                     ExcelStyles.ORDER_LINE_SIZE,
                                     ExcelStyles.ORDER_LINE_QUANTITY,
                                     ExcelStyles.ORDER_LINE_PRICE,
                                     ExcelStyles.ORDER_LINE_COST
        };

        // order items
        for(int i = 0; i < orderLineList.size(); i++) {
            OrderLineData orderLineData = orderLineList.get(i);
            HSSFRow row = sheet.createRow(currRow++);
            row.setHeightInPoints((short)14.25);

            ItemData itemData = orderLineData.getItemData();

            List<String> orderLineInfo = createOrderLineInfoRow(itemData.getName(),
                                                                itemData.getLength(),
                                                                orderLineData.getQuantity(),
                                                                orderLineData.getPrice(),
                                                                orderLineData.getPrice() * orderLineData.getQuantity());
            for(int j = 0; j < orderLineInfo.size(); j++) {
                HSSFCell cell = row.createCell(j + 1);
                cell.setCellValue(orderLineInfo.get(j));
                cell.setCellStyle(styles.get(orderLineStyles[j]));
            }
        }

        // order cost
        HSSFRow totalRow = sheet.createRow(currRow += 3);
        totalRow.setHeightInPoints((float)15);
        HSSFCell totalString = totalRow.createCell(4);
        totalString.setCellValue("Итого:");
        totalString.setCellStyle(styles.get(ExcelStyles.ORDER_TOTAL));
        HSSFCell totalPrice = totalRow.createCell(5);
        DecimalFormat currency = new DecimalFormat("#0.00р");
        totalPrice.setCellValue(order.getPrice() == null ? "unknown" : currency.format(order.getPrice()) + ".");
        totalPrice.setCellStyle(styles.get(ExcelStyles.ORDER_TOTAL));

        // signs row
        HSSFRow signRow = sheet.createRow(currRow += 5);
        // sender sign
        HSSFCell signSenderCell = signRow.createCell(1);
        signSenderCell.setCellValue("Отпустил:");
        signSenderCell.setCellStyle(styles.get(ExcelStyles.SENDER_SIGN));

        // customer sign
        HSSFCell signCustomerCell = signRow.createCell(3);
        signCustomerCell.setCellValue("Получил:");
        signCustomerCell.setCellStyle(styles.get(ExcelStyles.CUSTOMER_SIGN));
        signRow.createCell(4).setCellStyle(styles.get(ExcelStyles.CUSTOMER_SIGN));
        signRow.createCell(5).setCellStyle(styles.get(ExcelStyles.CUSTOMER_SIGN));

        // columns width
        double[] columnsWidth = { 11.29, 32.29, 10, 10.14, 10.14, 13.86 };
        for(int i = 0; i < columnsWidth.length; i++) {
            sheet.setColumnWidth(i, convertFromPoints(columnsWidth[i]));
        }

        // write file
        String fileName = order.getCustomerId() + "_" + order.getId() + fileFormat;
        FileOutputStream out = new FileOutputStream(fileName);
        wb.write(out);
        out.flush();
        out.close();

        return fileName;
    }

    private String writePaymentReport(Integer orderId){
        String filename = null;

        return filename;
    }

    private List<String> createOrderLineInfoRow(String label, 
                                                Integer length,
                                                Integer quantity,
                                                Double price,
                                                Double cost) {
        DecimalFormat currency = new DecimalFormat("#0.00р");
        List<String> orderLineInfo = new ArrayList<String>();
        orderLineInfo.add(label == null ? "unknown" : label);
        orderLineInfo.add(length == null ? "unknown" : length.toString());
        orderLineInfo.add(quantity == null ? "unknown" : quantity.toString());
        orderLineInfo.add(price == null ? "unknown" : currency.format(price) + ".");
        orderLineInfo.add(cost == null ? "unknown" : currency.format(cost) + ".");
        return orderLineInfo;
    }

    /**
     * convert excel points to parameter of <tt>HSSFSheet.setColumnWidth()</tt>
     * method
     * @param excelWidth
     * @return
     */
    private int convertFromPoints(double excelWidth) {
        return (int) (excelWidth / 0.003772);
    }

    private String dateToString(Date date) {
        String dateAsStr = "";
        try{
            dateAsStr = sdf.format(date);
        }catch(Exception e){
            Logger log = Logger.getLogger( ExcelFileWriter.class);
            log.error(e);

        }
//        String result = "";
//        Integer month = calendar.get(Calendar.MONTH);
//        Integer year = calendar.get(Calendar.YEAR);
//        Integer day = calendar.get(Calendar.DAY_OF_MONTH);
//        result += (day / 10 < 1 ? "0" : "") + day + ".";
//        result += (month / 10 < 1 ? "0" : "") + month + ".";
//        result += year + " г.";
//        return result;
        return dateAsStr;
    }
}
